home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Burning & Media / GB-PVR 1.2.13 / GBPVR10213.msi / Cabs.w1.cab / Guide2.aspx.cs588 < prev    next >
Text File  |  2008-02-23  |  30KB  |  633 lines

  1. using System;
  2. using System.Collections;
  3. using System.IO;
  4. using System.Web;
  5. using System.Web.Caching;
  6. using System.Web.UI;
  7. using System.Web.UI.HtmlControls;
  8. using System.Web.UI.WebControls;
  9. using GBPVR.Public;
  10. using GBPVRSchedule;
  11. using gbweb.classes;
  12.  
  13. namespace gbweb
  14. {
  15.     /// <summary>
  16.     /// Summary description for guide.
  17.     /// </summary>
  18.     public partial class guide2 : Page
  19.     {
  20.         protected HtmlImage IMG4;
  21.         protected HtmlImage IMG5;
  22.  
  23.         private DateTime startTime;
  24.         private Settings guideParams;
  25.  
  26.         //Guide display values that are stored in the users cookie
  27.         private static int minuteSpan;
  28.         private static int minuteInterval;
  29.         private static int minuteSlice;
  30.         private static string useChannelIcons;
  31.         private static string channelIconHeight;
  32.         private static string channelIconWidth;
  33.         private GuideListing Guide;
  34.  
  35.         protected void Page_Load(object sender, EventArgs e)
  36.         {
  37.             guideParams = Global.Settings;
  38.             Session["GuideStartTime"] = null;
  39.             GetCookieValues();
  40.  
  41.             //Code to prevent Guest users from accessing the Admin and search Pages
  42.             if (!Convert.ToBoolean((string)Session["NotGuestUser"]))
  43.             {
  44.                 NAV_SEARCH.Visible = false;
  45.                 NAV_CONFIG.Visible = false;
  46.             }
  47.  
  48.             if (!IsPostBack)
  49.             {
  50.                 //Set the header tab of the Guide to active
  51.                 NAV_GUIDE.Attributes.Add("class", "currentTab");
  52.                 NAV_RECORDINGS.Visible = guideParams.showManage;
  53.                 if (Convert.ToBoolean((string)Session["NotGuestUser"]))
  54.                 {
  55.                     NAV_SEARCH.Visible = guideParams.showSearch;
  56.                 }
  57.                 NAV_VIDEO.Visible = guideParams.showVideoLib;
  58.                 NAV_MUSIC.Visible = guideParams.showMusicLib;
  59.                 NAV_PHOTO.Visible = guideParams.showPhotoLib;
  60.                 NAV_STATS.Visible = guideParams.showStats;
  61.                 
  62.                 // populate date/time navigation controls
  63.                 DateTime today = DateTime.Today;
  64.  
  65.                 for (int hours = 0; hours < 24; hours++)
  66.                 {
  67.                     DateTime theHour = today.AddHours(hours);
  68.                     for (int minutes = 0; minutes < 60; minutes = minutes + minuteInterval)
  69.                     {
  70.                         DateTime theMinute = theHour.AddMinutes(minutes);
  71.                         ListItem myLI = new ListItem(theMinute.ToShortTimeString(), theMinute.ToString("HH:mm"));
  72.                         timeJump.Items.Add(myLI);
  73.                     }
  74.                 }
  75.                 Global.FillGenreList(genreList);
  76.             }
  77.  
  78.             if (ViewState["GuideStartTime"] == null)
  79.             {
  80.                 if (guideParams.guideStartTime != "")
  81.                 {
  82.                     // default the start time to the configured default start time
  83.                     startTime = Convert.ToDateTime(DateTime.Now.ToShortDateString() + " " + guideParams.guideStartTime);
  84.                 }
  85.                 else
  86.                 {
  87.                     // default to current time if the user has just logged in, or come from the 'manage recordings' page
  88.                     startTime = DateTime.Now;
  89.                 }
  90.  
  91.                 // remove seconds and miliseconds
  92.                 startTime = startTime.AddSeconds(-startTime.Second);
  93.                 startTime = startTime.AddMilliseconds(-startTime.Millisecond);
  94.             }
  95.             else
  96.             {
  97.                 startTime = (DateTime)ViewState["GuideStartTime"];
  98.             }
  99.  
  100.             //This checks to see if the user clicked next or previous to go to the next or go back to the previous
  101.             //timeline
  102.             if (Request.Form["__EVENTTARGET"] != null)
  103.             {
  104.                 if (Request.Form["__EVENTTARGET"].IndexOf("viewleftbutton") != -1) ViewLeftButton_Click(null, null);
  105.                 if (Request.Form["__EVENTTARGET"].IndexOf("viewrightbutton") != -1) ViewRightButton_Click(null, null);
  106.             }
  107.  
  108.         }
  109.  
  110.         #region Web Form Designer generated code
  111.         override protected void OnInit(EventArgs e)
  112.         {
  113.             //
  114.             // CODEGEN: This call is required by the ASP.NET Web Form Designer.
  115.             //
  116.             InitializeComponent();
  117.             base.OnInit(e);
  118.         }
  119.  
  120.         /// <summary>
  121.         /// Required method for Designer support - do not modify
  122.         /// the contents of this method with the code editor.
  123.         /// </summary>
  124.         private void InitializeComponent()
  125.         {
  126.  
  127.         }
  128.         #endregion
  129.  
  130.         //Jump to  the date and time that the user selected
  131.         protected void GoButton_Click(object sender, EventArgs e)
  132.         {
  133.             startTime = DateTime.Parse(dateJump.SelectedValue + " " + timeJump.SelectedValue);
  134.         }
  135.  
  136.         //Go back to the previous timeline
  137.         private void ViewLeftButton_Click(object sender, ImageClickEventArgs e)
  138.         {
  139.             startTime = startTime.AddMinutes(-minuteSpan);
  140.         }
  141.  
  142.         //Go to the next timeline
  143.         private void ViewRightButton_Click(object sender, ImageClickEventArgs e)
  144.         {
  145.             startTime = startTime.AddMinutes(minuteSpan);
  146.         }
  147.  
  148.         protected void Page_PreRender(object sender, EventArgs e)
  149.         {
  150.  
  151.             Schedule scheduleHelper = Global.Schedule;
  152.             ProgrammeDisplay2 displayProgramme = new ProgrammeDisplay2();
  153.  
  154.             // build up a list of the recording we already know about
  155.             IDictionary knownRecordings = scheduleHelper.LoadKnownRecordings();
  156.  
  157.             // normalize time period
  158.             startTime = startTime.AddMinutes(-startTime.Minute % minuteInterval);
  159.             DateTime endTime = startTime.AddMinutes(minuteSpan);
  160.  
  161.             //Set the Day/date/time display on the header
  162.             viewDate.InnerText = startTime.ToLongDateString().Trim();
  163.             serverTime.InnerText = "Server Time: " + DateTime.Now.ToLongTimeString().Trim();
  164.  
  165.             // store start time away for later use
  166.             ViewState["GuideStartTime"] = startTime;
  167.  
  168.             // select the correct minutes setting
  169.             timeJump.SelectedValue = startTime.ToString("HH:mm");
  170.  
  171.             //Build the drop down list of days and times the user can jump to
  172.             int listoffset = (startTime.Date - DateTime.Today).Days;
  173.             if (listoffset < 0) listoffset = 0;
  174.             if (listoffset > 6) listoffset = 6;
  175.             DateTime jumpDate = startTime.AddDays(-listoffset);
  176.  
  177.             dateJump.Items.Clear();
  178.             for (int nCount = -1; nCount <= 14; nCount++)
  179.             {
  180.                 DateTime theDay = jumpDate.AddDays(nCount);
  181.                 //ListItem myLI = new ListItem(theDay.ToLongDateString(), theDay.ToShortDateString());
  182.                 ListItem myLI = new ListItem(theDay.ToString("ddd, MMM dd, yyyy"), theDay.ToShortDateString());
  183.                 dateJump.Items.Add(myLI);
  184.             }
  185.  
  186.             dateJump.SelectedValue = startTime.ToShortDateString();
  187.  
  188.  
  189.             // retrieve listings for time period
  190.             IList listingsForPeriod;
  191.             listingsForPeriod = scheduleHelper.GetListingsForTimePeriod(startTime.AddSeconds(1), endTime);
  192.             ((ArrayList)listingsForPeriod).Sort(new ChannelNumberComparer());
  193.  
  194.             //Check to see if the user has selected a Genre to filter the shows on
  195.             CaseInsensitiveComparer caseInsensitiveComparer = new CaseInsensitiveComparer();
  196.             string genreFilter = genreList.SelectedValue;
  197.             if ((genreFilter != null) && (genreFilter.Length == 0)) genreFilter = null;
  198.  
  199.             //Create a new guide object
  200.             Guide = new GuideListing(Response);
  201.  
  202.             //The below variables are used to calculate where the programs should fall on the timeline.
  203.             //
  204.             //Set the variable for the default channel column margin
  205.             int channelColMargin = 7;
  206.             //Set the variable for programme offset margin to be in the correct position
  207.             int time_margin = channelColMargin;
  208.             //Set the display line remaining variable
  209.             int remainingDisplay = 100 - time_margin;
  210.             //Default the running width
  211.             int runWidth = 0;
  212.             //Default the running margin
  213.             int runMargin = channelColMargin;
  214.             //Default the running time
  215.             int runTime = 0;
  216.  
  217.             //set the corner block of the header of showtimes
  218.             Guide.addShowtimesLineLeftCorner(time_margin, true);
  219.             //set the variable to show the right hand scroll to next timeline page to false
  220.             bool showRightScroll = false;
  221.  
  222.             //set the times that are to be shown along the top of the guide
  223.             for (int mins = 0; mins < minuteSpan; mins += minuteInterval)
  224.             {
  225.                 //Increment the running time
  226.                 runTime += minuteInterval;
  227.                 //Calculate the correct width
  228.                 int width = Convert.ToInt32(Math.Floor(Convert.ToDecimal((Convert.ToDecimal(Convert.ToDecimal(runTime) / Convert.ToDecimal(minuteSpan))) * remainingDisplay))) - runWidth;
  229.                 //Increment the running width
  230.                 runWidth += width;
  231.                 //Increment the running margin
  232.                 runMargin += width;
  233.                 //Check to make sure that the width we just calculated does not exceed the max of the display area
  234.                 if (runWidth > remainingDisplay)
  235.                 {
  236.                     width = width - (runWidth - remainingDisplay);
  237.                     runWidth = remainingDisplay;
  238.                 }
  239.                 if (runMargin == 100)
  240.                 {
  241.                     showRightScroll = true;
  242.                 }
  243.                 Guide.addShowtimesLine((runMargin - width), width, startTime.AddMinutes(mins).ToShortTimeString());
  244.             }
  245.  
  246.             //Output the timeline header
  247.             forcedScrollbar.InnerHtml = Guide.getGuide();
  248.  
  249.             //Reintialize the guide listing control
  250.             Guide.Initailize();
  251.  
  252.             //Set the divsion id variable to the intitial value
  253.             string divIdValue = "guideRow";
  254.  
  255.             //Create a divsion for each channel
  256.             foreach (Channel channel in listingsForPeriod)
  257.             {
  258.                 //Start off by assuiming we are not going to show the channel line.  We only want to show it if
  259.                 //there is at least one programme to display
  260.                 bool showChannel = false;
  261.                 
  262.                 //Set the channel name and number
  263.                 string channelName = channel.getName();
  264.                 if (channelName.StartsWith(channel.getChannelNumber().ToString())) // cosmetic stuff for my american friends
  265.                 {
  266.                     if (channelName != channel.getChannelNumber().ToString())
  267.                     {
  268.                         channelName = channelName.Substring(channel.getChannelNumber().ToString().Length + 1);
  269.                     }
  270.                     else
  271.                     {
  272.                         channelName = "";
  273.                     }
  274.                 }
  275.  
  276.                 //Check to see if there is a channel icon for the channel
  277.                 string chnl = channel.getChannelNumber().ToString();
  278.                 string channelIcon = GetChannelIcon(channel.getChannelNumber(), new string[] { channel.getName(), channelName });
  279.  
  280.                 //Set variable used in calculting the shows position on the timeline
  281.                 DateTime prevEndTime = startTime;
  282.                 
  283.                 //Running variables used to position the show correctly on the timeline
  284.                 //
  285.                 //Set the display line remaining variable
  286.                 remainingDisplay = 100 - channelColMargin;
  287.                 //Default the running width
  288.                 runWidth = 0;
  289.                 //Default the running margin
  290.                 runMargin = channelColMargin;
  291.                 //Default the running time
  292.                 runTime = 0;
  293.                 
  294.                 //Variable used to signify that we have or have not found at least one show....as soon as a
  295.                 //show is found then we will create the line for the channel....otherwise (nothing being found)
  296.                 //the channel will not show up on the listing
  297.                 bool deadChannel = true;
  298.  
  299.                 //Loop through each programme for the channel to format it for display
  300.                 foreach (Programme programme in channel.getProgrammeList())
  301.                 {
  302.                     int startMinutes = 0;
  303.                     int endMinutes = 0;
  304.                     DateTime programStartTime = programme.getStartTime();
  305.  
  306.                     // check to see if there are 'gaps' in the schedule that we need to pad
  307.                     if (prevEndTime < programStartTime)
  308.                     {
  309.                         TimeSpan stimespan = prevEndTime.Subtract(startTime);
  310.                         startMinutes = (int)Math.Round(stimespan.TotalMinutes);
  311.  
  312.                         TimeSpan etimespan = programme.getStartTime().Subtract(startTime);
  313.                         endMinutes = (int)Math.Round(etimespan.TotalMinutes);
  314.                         
  315.                         //Add a dummy filler cell to ensure the programm falls in the right spot on the timeline
  316.                         
  317.                         //Increment the running time
  318.                         runTime += (endMinutes - startMinutes);
  319.                         int width = Convert.ToInt32(Math.Floor(Convert.ToDecimal((Convert.ToDecimal(Convert.ToDecimal(runTime) / Convert.ToDecimal(minuteSpan))) * remainingDisplay))) - runWidth;
  320.  
  321.                         //Increment the running width
  322.                         runWidth += width;
  323.  
  324.                         //Increment the running margin
  325.                         runMargin += width;
  326.  
  327.                         //Check to make sure that the width we just calculated does not exceed the max of the display area
  328.                         if (runWidth > remainingDisplay)
  329.                         {
  330.                             width = width - (runWidth - remainingDisplay);
  331.                             runWidth = remainingDisplay;
  332.                         }
  333.                         Guide.addDisplayLine("listing", (runMargin - width), width, "<div class=\"showTitle\" title=\"No Programming Available\">No Programming Available</div>");
  334.                     }
  335.                     else if (prevEndTime > programStartTime)
  336.                     {
  337.                         //This allows for programs that overlap, we just let the previous program spill into the next
  338.                         //  and the later program looks like it starts later
  339.                         programStartTime = prevEndTime;
  340.                     }
  341.  
  342.                     //Calculate start minutes
  343.                     if (programStartTime <= startTime)
  344.                     {
  345.                         startMinutes = 0;
  346.                     }
  347.                     else
  348.                     {
  349.                         TimeSpan timespan = programStartTime.Subtract(startTime);
  350.                         startMinutes = (int)Math.Round(timespan.TotalMinutes);
  351.                     }
  352.  
  353.                     //Calculate end minutes
  354.                     if (programme.getEndTime() >= endTime)
  355.                     {
  356.                         endMinutes = minuteSpan;
  357.                     }
  358.                     else
  359.                     {
  360.                         TimeSpan timespan = programme.getEndTime().Subtract(startTime);
  361.                         endMinutes = (int)Math.Round(timespan.TotalMinutes);
  362.                     }
  363.  
  364.                     //Check for programs that we can't display,
  365.                     //  they may either be too narrow, or
  366.                     //  they overlap with other programs
  367.                     if ((endMinutes - startMinutes) / minuteSlice < 1) continue;
  368.  
  369.                     prevEndTime = programme.getEndTime();
  370.  
  371.                     //Assume that we will be displaying the programme currently being processed
  372.                     bool showProgramme = true;
  373.                     
  374.                     //Check to see if the user selected a genrea filter
  375.                     //if (genreFilter != null && genreFilter.Length > 0)
  376.                     if (genreFilter != "Choose Genre...")
  377.                     {
  378.                         //If there are genres on the programme check to see if it matches what the user selected
  379.                         if (programme.getGenreList().Count > 0)
  380.                         {
  381.                             ArrayList showGenres = new ArrayList(programme.getGenreList());
  382.                             showGenres.Sort();
  383.                             int idx = showGenres.BinarySearch(genreList.SelectedValue, caseInsensitiveComparer);
  384.                             showProgramme = idx > -1;
  385.                         }
  386.                         //Since no genres were on the programme then exclude it from view
  387.                         else
  388.                         {
  389.                             showProgramme = false;
  390.                         }
  391.                     }
  392.  
  393.                     //Since we are still showing the programme we need to place it on the timeline in the correct
  394.                     //position
  395.                     if (showProgramme)
  396.                     {
  397.                         ScheduledRecording scheduledRecording = null;
  398.                         if (knownRecordings.Contains(programme.getOID())) scheduledRecording = (ScheduledRecording)knownRecordings[programme.getOID()];
  399.                         //We are using a TableCell to hold the formatted display information only....it is just a container
  400.                         //
  401.                         TableCell programmeCell = new TableCell();
  402.                         
  403.                         //Call the common routine to format the display information
  404.                         displayProgramme.FillProgrammeDisplay(Server, programmeCell, programme, scheduledRecording, true);
  405.                         
  406.                         //Increment the running time
  407.                         runTime += (endMinutes - startMinutes);
  408.                         int width = Convert.ToInt32(Math.Floor(Convert.ToDecimal((Convert.ToDecimal(Convert.ToDecimal(runTime) / Convert.ToDecimal(minuteSpan))) * remainingDisplay))) - runWidth;
  409.                         
  410.                         //Increment the running width
  411.                         runWidth += width;
  412.                         
  413.                         //Increment the running margin
  414.                         runMargin += width;
  415.                        
  416.                         //Check to make sure that the width we just calculated does not exceed the max of the display area
  417.                         if (runWidth > remainingDisplay)
  418.                         {
  419.                             width = width - (runWidth - remainingDisplay);
  420.                             runWidth = remainingDisplay;
  421.                         }
  422.                         
  423.                         //Set the correct color display for the listing based on the CssClass that was passed back
  424.                         //on the TableCell by the common display formatting routine
  425.  
  426.                         string displayClass = programmeCell.CssClass;
  427.  
  428.                         //If showChannel is false it means we have not yet produced a line for the channel so 
  429.                         //we need to create the start of the line which holds the channel name and icon
  430.                         if (!showChannel)
  431.                         {
  432.                             //Set the variable so that we do not come back through here again for this channel
  433.                             showChannel = true;
  434.                             
  435.                             //Start the guide area for the actual programme listings for the current channel
  436.                             Guide.addStartDivLine("ch" + chnl, "guideRow");
  437.  
  438.                             //Set the display class for the users channel icon/text selection
  439.                             string dispClass = string.Empty;
  440.                             if (useChannelIcons == "chnlBoth")
  441.                             {
  442.                                 dispClass = "channelInfoLogoAndText";
  443.                             }
  444.                             else
  445.                             {
  446.                                 if (useChannelIcons == "chnlText")
  447.                                 {
  448.                                     dispClass = "channelInfo";
  449.                                 }
  450.                                 else
  451.                                 {
  452.                                     dispClass = "channelInfoLogoOnly";
  453.                                 }
  454.                             }
  455.                             
  456.                             //If there is a channel icon to display we need to set the appropriate formatting based on the
  457.                             //display % that the user has selected in the Config page
  458.                             if (channelIcon != null)
  459.                             {
  460.                                 //Add the channel information to the Array that holds all the display information for the guide
  461.                                 Guide.addDisplayChannel(dispClass, chnl + " " + channelName, channelColMargin, "SearchResults2.aspx?listChannels=" + chnl + "&srtOrder=title\"",
  462.                                                         chnl, channelName, "SearchResults2.aspx?listChannels=" + chnl + "&srtOrder=title\"", Download.GetDownloadUrl(false, true, Download.InternalFiles.ChannelIcon, Server.UrlEncode(channelIcon)));
  463.                             }
  464.                             else
  465.                             {
  466.                                 //Since there is no channel icon format the line appropriatley and add it to the Array
  467.                                 //that holds all the display information for the guide
  468.                                 Guide.addDisplayChannel("channelInfo", chnl + " " + channelName, channelColMargin, "SearchResults2.aspx?listChannels=" + chnl + "&srtOrder=title\"",
  469.                                                         chnl, channelName, "", "");
  470.                             }
  471.                         }
  472.                         //Add the formatted programme information to the Array that holds all the display information for the guide
  473.                         Guide.addDisplayLine(displayClass, (runMargin - width), width, programmeCell.Text);
  474.                     }
  475.                     //We are not going to display the current programme but we still need to update variables
  476.                     //used to position the next programme
  477.                     else
  478.                     {
  479.                         //Increment the running time
  480.                         runTime += (endMinutes - startMinutes);
  481.                         //Calculate the correct width
  482.                         int width = Convert.ToInt32(Math.Floor(Convert.ToDecimal((Convert.ToDecimal(Convert.ToDecimal(runTime) / Convert.ToDecimal(minuteSpan))) * remainingDisplay))) - runWidth;
  483.                         //Increment the running width
  484.                         runWidth += width;
  485.                         //Increment the running margin
  486.                         runMargin += width;
  487.                         //Check to make sure that the width we just calculated does not exceed the max of the display area
  488.                         if (runWidth > remainingDisplay)
  489.                         {
  490.                             width = width - (runWidth - remainingDisplay);
  491.                             runWidth = remainingDisplay;
  492.                         }
  493.                     }
  494.                 }
  495.                 //Set the end the line for the current channel as long as there was at least one show on that
  496.                 //channel to display
  497.                 if (showChannel)
  498.                 {
  499.                     Guide.addEndDivLine();
  500.                 } 
  501.             }
  502.             
  503.             //This fills the content area with all the guide information that was built in the Array
  504.             CONTENTS.InnerHtml = Guide.getGuide();
  505.             CONTENTS.Attributes.Add("onscroll", "fScroll(this)");
  506.             
  507.             //Reset the Guide object to dump everything from memory
  508.             Guide.Initailize();
  509.             //Get rid of the displayProgramme object 
  510.             displayProgramme.Dispose();
  511.         }
  512.  
  513.         private void GetCookieValues()
  514.         {
  515.             HttpCookie cookie = Request.Cookies["minuteSpan"];
  516.             minuteSpan = cookie != null ? Convert.ToInt32(cookie.Value) : 120;
  517.  
  518.             cookie = Request.Cookies["minuteInterval"];
  519.             minuteInterval = cookie != null ? Convert.ToInt32(cookie.Value) : 30;
  520.  
  521.             cookie = Request.Cookies["minuteSlice"];
  522.             minuteSlice = cookie != null ? Convert.ToInt32(cookie.Value) : 1;
  523.  
  524.             cookie = Request.Cookies["useChannelIcons"];
  525.             useChannelIcons = cookie != null ? cookie.Value : "chnlText";
  526.  
  527.             cookie = Request.Cookies["channelIconHeight"];
  528.             channelIconHeight = cookie != null ? cookie.Value : "";
  529.  
  530.             cookie = Request.Cookies["channelIconWidth"];
  531.             channelIconWidth = cookie != null ? cookie.Value : "";
  532.  
  533.         }
  534.  
  535.         private static string channelIconPath;
  536.         private static string[] channelIconExtensions;
  537.  
  538.         public string GetChannelIcon(int channelNumber, string[] channelNames)
  539.         {
  540.             // Get the Channel Icon Directory
  541.             if (channelIconPath == null)
  542.             {
  543.                 lock (typeof(guide2))
  544.                 {
  545.                     if (channelIconPath == null)
  546.                     {
  547.                         channelIconPath = Path.Combine(Global.Settings.GetInstallDir(), @"media\ChannelLogos");
  548.                         channelIconExtensions = Global.Settings.channelIconExtensions.Split(',');
  549.                     }
  550.                 }
  551.             }
  552.  
  553.             Hashtable channelIconCache = (Hashtable)Cache["channelIconCache"];
  554.             if (channelIconCache == null)
  555.             {
  556.                 lock (typeof(guide2))
  557.                 {
  558.                     channelIconCache = (Hashtable)Cache["channelIconCache"];
  559.                     if (channelIconCache == null)
  560.                     {
  561.                         channelIconCache = new Hashtable();
  562.                         Cache.Add(
  563.                             "channelIconCache",
  564.                             channelIconCache,
  565.                             new CacheDependency(channelIconPath),
  566.                             DateTime.MaxValue,
  567.                             //DateTime.Now.AddMinutes(30),
  568.                             //TimeSpan.Zero,
  569.                             Cache.NoSlidingExpiration,
  570.                             CacheItemPriority.Normal,
  571.                             null);
  572.                     }
  573.                 }
  574.             }
  575.  
  576.             if (channelIconCache.ContainsKey(channelNumber))
  577.             {
  578.                 return (string)channelIconCache[channelNumber];
  579.             }
  580.  
  581.             lock (channelIconCache)
  582.             {
  583.                 if (channelIconCache.ContainsKey(channelNumber))
  584.                 {
  585.                     return (string)channelIconCache[channelNumber];
  586.                 }
  587.  
  588.                 string channelIconFile = null;
  589.                 foreach (string channelName in channelNames)
  590.                 {
  591.                     foreach (string channelIconExtension in channelIconExtensions)
  592.                     {
  593.                         string cleanName = channelName;
  594.                         string channelNameWork = channelName;
  595.                         while (cleanName.Contains("/"))
  596.                         {
  597.                             if (channelNameWork.Contains("/"))
  598.                             {
  599.                                 cleanName = channelNameWork.Remove(channelNameWork.IndexOf("/"), 1);
  600.                                 channelNameWork = cleanName;
  601.                             }
  602.                         }
  603.                         string probeFile = cleanName + "." + channelIconExtension;
  604.                         if (File.Exists(Path.Combine(channelIconPath, probeFile)))
  605.                         {
  606.                             channelIconFile = probeFile;
  607.                             break;
  608.                         }
  609.                     }
  610.                     if (channelIconFile != null) break;
  611.                 }
  612.                 channelIconCache[channelNumber] = channelIconFile;
  613.                 return channelIconFile;
  614.             }
  615.         }
  616.  
  617.         private class ChannelNumberComparer : IComparer
  618.         {
  619.  
  620.             #region IComparer Members
  621.  
  622.             public int Compare(object x, object y)
  623.             {
  624.                 return ((Channel)x).channelNumber.CompareTo(((Channel)y).channelNumber);
  625.             }
  626.  
  627.             #endregion
  628.  
  629.         }
  630.  
  631.     }
  632. }
  633.